package com.ac.scum.log.web.task;

import com.ac.scum.log.bean.PlayerAlarm;
import com.ac.scum.log.bean.PlayerAlarmError;
import com.ac.scum.log.web.model.player.mapper.PlayerAlarmErrorMapper;
import com.ac.scum.log.web.model.player.mapper.PlayerAlarmMapper;
import com.ac.scum.log.web.model.player.mapper.PlayerAlarmPushedMapper;
import com.ac.scum.log.web.model.wechat.mp.mapper.WeChatUserPlayerMapper;
import com.ac.scum.log.web.model.wechat.mp.service.TemplateSendService;
import com.ac.scum.wechat.bean.WechatUserPlayer;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@Component
@AllArgsConstructor
public class WeChatTemplateMessageTask {
    private final RedissonClient redissonClient;
    private final PlayerAlarmMapper playerAlarmMapper;
    private final TemplateSendService templateSendService;
    private final WeChatUserPlayerMapper weChatUserPlayerMapper;
    private final PlayerAlarmErrorMapper playerAlarmErrorMapper;
    private final PlayerAlarmPushedMapper playerAlarmPushedMapper;

    private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

    @Scheduled(cron = "0/20 * * * * ?")
    public void serverLogsUpdateConsumer() {
        Page<PlayerAlarm> playerAlarmPage = playerAlarmMapper.selectPage(new Page<>(1, 500), Wrappers.emptyWrapper());
        if (playerAlarmPage.getTotal() > 0) {
            List<WechatUserPlayer> wechatUserPlayers = weChatUserPlayerMapper.selectList(Wrappers.lambdaQuery(WechatUserPlayer.class).in(WechatUserPlayer::getPlayerId, playerAlarmPage.getRecords().stream().map(PlayerAlarm::getPlayerId).toList()));
            log.info("♥当前待推送模板消息共{}条", playerAlarmPage.getTotal());
            AtomicInteger successCount = new AtomicInteger(0);
            AtomicInteger errorCount = new AtomicInteger(0);
            playerAlarmPage.getRecords().forEach(item -> {
                RLock lock = redissonClient.getLock("alarm_consumer_" + item.getId());
                try {
                    if (lock.tryLock()) {
                        Optional<WechatUserPlayer> first = wechatUserPlayers.stream().filter(wechatUserPlayer -> Objects.equals(wechatUserPlayer.getPlayerId(), item.getPlayerId())).findFirst();
                        if (first.isPresent()) {
                            String messageId = templateSendService.sendTemplate(first.get().getOpenId(),
                                    "a9nPDvgWzg1p6kdJXTOGaTzO6ul77Sb3BkuPtV2Hk-4",
                                    Lists.newArrayList(
                                            new WxMpTemplateData("time3", dateFormatter.format(item.getLogTime())),
                                            new WxMpTemplateData("thing40", item.getServerName()),
                                            new WxMpTemplateData("thing70", item.getAlarmDetail()),
                                            new WxMpTemplateData("thing95", item.getAlarmItem())
                                    ));
                            if (StringUtils.isNotBlank(messageId)) {
                                successCount.incrementAndGet();
                                playerAlarmMapper.deleteById(item.getId());
                                playerAlarmPushedMapper.insert(item.PushedEntity());
                            } else {
                                errorCount.incrementAndGet();
                                playerAlarmErrorMapper.insert(item.PushedErrorEntity("微信通知失败"));
                            }
                        } else {
                            errorCount.incrementAndGet();
                            playerAlarmErrorMapper.insert(item.PushedErrorEntity("未获取到玩家绑定微信的绑定信息"));
                        }
                    }
                } catch (Exception e) {
                    errorCount.incrementAndGet();
                    PlayerAlarmError pushedError = item.PushedErrorEntity(e.getMessage());
                    playerAlarmErrorMapper.insert(pushedError);
                    playerAlarmMapper.deleteById(item.getId());
                    log.error("推送微信模板消息失败：{}", e.getMessage(), e);
                } finally {
                    lock.unlock();
                }
            });
            log.info("♥成功推送消息{}条 失败{}条 共{}条", successCount.get(), errorCount.get(), successCount.get() + errorCount.get());
        }

    }
}
